(function ($) {
    $.fn.yqRuntime = function (opts, param) {
        if (typeof opts == 'string') {
            return $.fn.yqRuntime.methods[opts](this, param);
        }

        return this.each(function () {
            $this = $(this);
            var opt;
            if ($this.data("yqtype") == "yqRuntime") {
                opt = $.extend({}, options($this), opts);
            }
            else {
                opt = $.extend({}, $.fn.yqRuntime.defaults, opts);
                var $uniqueID = $this.attr("ID");
                if ($uniqueID === undefined) {
                    $uniqueID = "id_123123123";
                    $this.attr("ID", $uniqueID);
                }
            }

            if (opt.width === undefined && $this.width() > 0) {
                opt.width = $this.width();
            }
            else if (typeof opt.width != "undefined") {
                $this.width(opt.width);
            }

            if (opt.height === undefined && $this.height() > 0) {
                opt.height = $this.height();
            }
            else if (typeof opt.height != "undefined") {
                $this.height(opt.height);
            }

            //变量信息
            $this.data("runtime_opt", opt);
            $this.data("yqtype", "yqRuntime");

            init_ui($this);
        });
    };

    $.fn.yqRuntime.defaults = {
        afterBindingTitle: function () { },   //标题绑定后
    };

    $.fn.yqRuntime.methods = {
        options: function (jq) {
            return options($(jq[0]));
        },
        destroy: function (jq) {
            destroy($(jq[0]));
        },
        resize: function (jq, width) {
            resize($(jq[0]), width);
        },
        clear: function (jq) {
            setRows($(jq[0]), {});
        },
    };

    function form_load($object) {
        var opt = options($object);
        resize($object);
        opt.$menu_open.linkbutton('enable');

        opt.afterBindingTitle.call($object);
    }

    function options($object) {
        return $object.data("runtime_opt");
    }

    function destroy($object) {
        //$object.textbox("destroy");
    }

    function resize($object, params) {
        var opt = options($object);
        var $uniqueID = $object.attr("ID");

        if (!(params === undefined)) {
            if (!(params.width === undefined)) {
                opt.width = params.width;
            }
            if (!(params.height === undefined)) {
                opt.height = params.height;
            }
        }
        opt.$layout.layout("resize", {
            width: opt.width,
            height: opt.height
        });


        opt.$tabs.tabs("resize", {
            width: opt.$center.width(),
            height: opt.$center.height()
        });
    }

    function init_ui($object) {
        var opt = options($object);
        var $uniqueID = $object.attr("ID");

        var html_ = `
<div class="m-layout" style="width:700px;height:350px;">
    <div data-options="region:'north',border:true" style="height:36px">
        <form class="m-menu" style="padding:1px 0px 1px 1px;">
            <table style="border-spacing: 0px;padding:0;margin:0;">
              <tbody style="border-spacing: 0px;">
                <tr>
                  <td>
                    <a href="#" class="menu-open">open</a>
                    <a href="#" class="menu-close">close</a>
                    <a href="#" class="menu-clear">clear</a>
                    <input class="menu-heartbeat"/>
                    <input class="menu-remsg"/>
                  </td>
                  <td style="padding: 0 0 0 20px;">
                    <div class="menu-log"></div>
                  </td>  
                </tr>
              </tbody>
            </table>
        </form>    
    </div>
    <div data-options="region:'center',border:false">
        <div class="m-tabs easyui-tabs">
            <div title="日志" style="padding:10px;" data-options="id:'`+ $uniqueID + `panel_1'">
                <div class="log"></div>
            </div>
            <div title="Title2" style="padding:10px;" data-options="id:'`+ $uniqueID + `panel_2'">Content 2</div>
        </div>
    </div>
    <div data-options="region:'south',border:false" style="height:32px;">
        <div style="padding:2px 0px 0px 2px;">
            <input class="msg" type="text" size="64"/>
        </div>
    </div>
</div> 
            `;

        $object.append(html_);

        opt.$menu = $object.find(".m-menu");
        opt.$menu_open = $object.find(".menu-open");
        opt.$menu_close = $object.find(".menu-close");
        opt.$menu_clear = $object.find(".menu-clear");
        opt.$menu_heartbeat = $object.find(".menu-heartbeat");
        opt.$menu_remsg = $object.find(".menu-remsg");
        opt.$menu_log = $object.find(".menu-log");

        opt.$layout = $object.find(".m-layout");
        opt.$layout.layout({

        });

        opt.$center = opt.$layout.layout("panel", "center");

        opt.$tabs = $object.find(".m-tabs");
        opt.$tabs.tabs({});
        opt.$panel_1 = $("#" + $uniqueID + "panel_1");
        opt.$panel_2 = $("#" + $uniqueID + "panel_2");

        opt.$panel_1.css({
            "background-color": "black",
            "color": "white",
            "font-size": "smaller",
            "line-height": "150%"
        });

        opt.$msg = opt.$layout.find(".msg");
        opt.$log = opt.$layout.find(".log")

        //   window.addEventListener("load", function (evt) {
        opt.ws;

        opt.$msg.textbox({
            buttonText: 'Send',
            iconAlign: 'left',
            readonly: true,
            onClickButton: function () {
                if (!opt.ws) {
                    return false;
                }
                print("SEND: " + $(this).textbox("getValue"));
                opt.ws.send($(this).textbox("getValue"));
            }
        });

        var print = function (message) {
            var d = document.createElement("div");
            d.textContent = message;

            opt.$log[0].appendChild(d);

            var doScroll = opt.$panel_1[0].scrollTop < (opt.$panel_1[0].scrollHeight - opt.$panel_1[0].clientHeight);
            if (doScroll) {
                opt.$panel_1[0].scrollTop = opt.$panel_1[0].scrollHeight - opt.$panel_1[0].clientHeight;
            }
        };

        opt.$menu_open.linkbutton({
            iconCls: 'icon2-open',
            plain: true,
            disabled: true,
            onClick: function () {
                if (opt.ws) {
                    return false;
                }

                try {
                    var ws_url = "ws://" + window.location.host + "/_runtime.html?action=monitor";
                    opt.ws = new WebSocket(ws_url);
                    opt.ws.onerror = function (error) {
                        console.error("WebSocket[" + ws_url + "] error:", error);
                    };
                } catch (e) {
                    console.error("Failed to create WebSocket[" + ws_url + "]:", e);
                }

                opt.ws.onopen = function (evt) {
                    opt.$menu_open.linkbutton('disable');
                    opt.$menu_close.linkbutton('enable');
                    opt.$msg.textbox('readonly', false);

                    opt.$menu_heartbeat.switchbutton('uncheck');
                    opt.$menu_heartbeat.switchbutton('enable');

                    opt.$menu_remsg.switchbutton('uncheck');
                    opt.$menu_remsg.switchbutton('enable');

                    print("OPEN");
                }
                opt.ws.onclose = function (evt) {
                    opt.$menu_open.linkbutton('enable');
                    opt.$menu_close.linkbutton('disable');
                    opt.$msg.textbox('readonly', true);

                    opt.$menu_heartbeat.switchbutton('disable');

                    print("CLOSE");
                    opt.ws = null;
                }
                opt.ws.onmessage = function (evt) {
                    var rows = msgSplit(evt.data);
                    rows.forEach(row => {
                        var data = JSON.parse(row);
                        if (data.type == "heartbeat") {
                            console.log(data);
                        } else if (data.type == "log") {
                            console.log(data);
                            if (opt.ment_logset.includes(data.info.type)) {
                                var log_ = data.info.type + " " + data.info.ts;
                                if (data.info.file != "") {
                                    log_ += " " + data.info.file + ":" + data.info.line;
                                }
                                if (typeof data.info.msg == "object") {
                                    log_ += " " + JSON.stringify(data.info.msg);
                                } else {
                                    log_ += " " + data.info.msg;
                                }

                                print(log_);
                            }
                        } else {
                            print("RESPONSE: " + row);
                        }
                    });
                }
                opt.ws.onerror = function (evt) {
                    print("ERROR: " + (evt.data === undefined ? "WebSocket cannot connect." : evt.data));
                }
            }
        });

        opt.$menu_close.linkbutton({
            iconCls: 'icon2-close',
            plain: true,
            disabled: true,
            onClick: function () {
                if (!opt.ws) {
                    return false;
                }
                opt.ws.close();
            }
        });

        opt.$menu_clear.linkbutton({
            iconCls: 'icon2-clear',
            plain: true,
            onClick: function () {
                opt.$log[0].innerHTML = "";
                opt.$log[0].scrollTop = 0;
            }
        });

        opt.$menu_heartbeat.switchbutton({
            width: 95,
            checked: false,
            onText: 'heart on',
            offText: 'heart off',
            disabled: true,
            onChange: function (checked) {
                if (!opt.ws) {
                    return false;
                }

                var s_msg = '{"type":"setup","info":{"name":"heartbeat","value":' + (checked ? 'true' : 'false') + '}}';
                print("SEND: " + s_msg);
                opt.ws.send(s_msg);
            }
        });

        opt.$menu_remsg.switchbutton({
            width: 100,
            checked: false,
            onText: 'remsg on',
            offText: 'remsg off',
            disabled: true,
            onChange: function (checked) {
                if (!opt.ws) {
                    return false;
                }

                var s_msg = '{"type":"setup","info":{"name":"remsg","value":' + (checked ? 'true' : 'false') + '}}';
                print("SEND: " + s_msg);
                opt.ws.send(s_msg);
            }
        });

        opt.ment_logset = ['debug', 'info', 'warning', 'error', 'critical'];
        opt.$menu_log.checkgroup({
            name: 'fruit',
            value: opt.ment_logset,
            labelWidth: 77,
            data: [{
                value: 'debug',
                label: 'DEBUG'
            }, {
                value: 'info',
                label: 'INFO'
            }, {
                value: 'warning',
                label: 'WARNING'
            }, {
                value: 'error',
                label: 'ERROR'
            }, {
                value: 'critical',
                label: 'CRITICAL'
            }],
            onChange: function (values) {
                opt.ment_logset = values;
                console.log(values);
            }
        });

        form_load($object);
        // });

        function msgSplit(data) {
            var redata = [];
            var ss = data.split('}\n{');
            if (ss.length == 1) {
                redata.push(data);
            } else {
                for (var i = 0; i < ss.length; i++) {
                    if (i == 0) {
                        redata.push(ss[i] + "}");
                    } else if (i == (ss.length - 1)) {
                        redata.push("{" + ss[i]);
                    } else {
                        redata.push("{" + ss[i] + "}");
                    }
                }
            }

            return redata;
        }
    }
})(jQuery);
